/*
*	Pickout - Cool effect for field select on form
*	Copyright (c) 2016 Ktquez
*	Project repository: https://github.com/ktquez/pickout
* 	MIT license.
*/

var pickout = (function () {

    "use strict";

    // Own configuration of each field select
    var ownConfig = {};

    // Default values
    var defaults = {
        theme: 'clean',
        search: false
    };

    /**
     * Starts the module preparing the elements
     * @param config = String or object to setting
     */
    function init(config) {
        setElement(config);
        prepareElement();
    }

    /**
     * Defines the own configuration and assigns the select
     * @param {[type]} config = String or object to setting
     */
    function setElement(config) {

        var objConfig = typeof config === 'object' ? config : {};

        if (typeof config === 'string') {
            objConfig.el = config;
        }

        // Retrieve the DOM to be manipulated
        objConfig.DOM = [].slice.call(document.querySelectorAll(objConfig.el));

        mergeToDefaults(objConfig);
    }


    /**
     * Prepare the elements that will be handled by the module
     */
    function prepareElement() {

        ownConfig.DOM.map(function (select, index) {
            createElements(select, index);
        });

        prepareModal();
    }

    function createElements(select, index) {

        // Cache self config
        var config = ownConfig;

        select.style.display = 'none';

        var parent = select.parentElement;
        parent.setAttribute('style', 'position:relative;float:left;');
        var placeholder = select.getAttribute('placeholder');

        // input
        var input = document.createElement('textarea');
        input.setAttribute('id', 'textarea' + index);
        input.setAttribute('readonly', 'readonly');
        input.setAttribute('class', 'pk-input -' + config.theme);
        if (!!placeholder) input.setAttribute('placeholder', placeholder);

        if (parent.hasAttribute('for')) input.setAttribute('id', parent.getAttribute('for'));

        // Arrow
        var arrow = document.createElement('span');
        arrow.setAttribute('class', 'pk-arrow -' + config.theme);

        parent.appendChild(input);
        parent.appendChild(arrow);

        // Event listener
        parent.addEventListener('click', function (e) {
            e.preventDefault();
            e.stopPropagation();

            config.currentIndex = index;
            fireModal(config);
        }, false);


    }

    /**
     * Create and manage options in modal
     * @param  {Object} config = ownConfig
     */
    function fireModal(config) {

        var modal = document.querySelector('.pk-modal'),
            select = config.DOM[config.currentIndex],
            data;

        // modal theme
        modal.setAttribute('class', modal.getAttribute('class') + ' -' + config.theme);

        // Avoid charging again when changing tab and the field gives focus again
        var main = modal.querySelector('.main');
        if (!!main.children.length) {
            return;
        }

        var overlay = document.querySelector('.pk-overlay');
        var options = [].slice.call(select);

        var optionsModal = options.map(function (option, key) {
            data = {index: key, item: option};
            return createOption(data, modal, config);
        });

        // Displaying overlay and modal
        modal.setAttribute('class', modal.getAttribute('class') + ' -show');
        overlay.setAttribute('class', overlay.getAttribute('class') + ' -show');

        var title = select.hasAttribute('placeholder') ? select.getAttribute('placeholder') : 'Select to option';
        modal.querySelector('.head').innerHTML = title;

        // If search
        if (config.search) {
            var search = modal.querySelector('.pk-search');
            var inputSearch = search.querySelector('input');
            inputSearch.value = '';

            // Focus no field search
            setTimeout(function () {
                inputSearch.focus();
            }, 300);

            search.setAttribute('class', search.getAttribute('class') + ' -show');

            // Listener
            inputSearch.addEventListener('keyup', function (e) {
                e.preventDefault();
                e.stopPropagation();

                var optionsDefault = optionsModal,
                    main = modal.querySelector('.main');

                // Specific for IE
                if (!!document.documentMode) {
                    optionsModal.map(function (option) {
                        option.style.display = 'none';
                    });

                } else {
                    // Deletes the options
                    main.innerHTML = '';
                }


                // If the search field is empty
                if (!e.target.value) {
                    optionsDefault.map(function (option) {

                        // Specific for IE
                        if (!!document.documentMode) {
                            option.style.display = 'block';
                            return;
                        }

                        main.appendChild(option);
                    });
                    return;
                }

                // If any character typed
                optionsModal.map(function (option) {
                    // Recover text element
                    var txt = option.children[1] || option.children[0];
                    // Compares the search with the text option
                    if (txt.innerHTML.toLowerCase().indexOf(e.target.value.toLowerCase()) !== -1) {

                        // Specific for IE
                        if (!!document.documentMode) {
                            option.style.display = 'block';
                            return;
                        }

                        main.appendChild(option);
                    }
                });

                // No results
                if (!main.children.length) {
                    var noResults = document.createElement('li');
                    noResults.setAttribute('class', 'pk-no_result_search');
                    noResults.innerHTML = 'No Results';

                    main.appendChild(noResults);
                    return;
                }

            }, false);
        }

    }

    /**
     * Creates options for the chosen select
     * @param  {Object} data = {index, option}
     * @param  {object DOM} modal  = Modal that will receive the list
     * @param  {object} config
     */
    function createOption(data, modal, config) {

        var select = config.DOM[config.currentIndex];
        var main = modal.querySelector('.main');

        var item = document.createElement('li');
        var selected = data.item.hasAttribute('selected') ? '-selected' : '';
        item.setAttribute('class', 'pk-option ' + selected + ' -' + config.theme);

        var icon = document.createElement('span');
        icon.setAttribute('class', 'icon');
        icon.innerHTML = data.item.getAttribute('data-icon') || '';

        var txt = document.createElement('span');
        txt.setAttribute('class', 'txt');
        txt.innerHTML = data.item.innerHTML;

        main.appendChild(item);
        item.appendChild(icon);
        item.appendChild(txt);

        // Event listener
        item.addEventListener('click', function (e) {
            e.preventDefault();
            e.stopPropagation();

            // Converting to array, because it is a (object) HTMLCollection
            [].slice.call(select.children).map(function (item, index) {
                if (index === data.index) {
                    item.setAttribute('selected', 'selected');
                    return;
                }

                item.removeAttribute('selected');
            });

            feedInput(select, txt.innerHTML, config.currentIndex);
            closeModal();
        }, false);

        return item;
    }

    function feedInput(select, value, index) {
        select.parentElement.querySelector('.pk-input').value = value;
        if (index == 0 | index == undefined) {
            getDoctorByInstitutionId();
        }
    }

    /**
     * Sets a value (option) default for field select
     */
    function setInitialValue(config) {
        setElement(config);

        ownConfig.DOM.map(function (select) {
            feedInput(select, select[select.selectedIndex].innerHTML, config.currentIndex);
        });
    }

    /**
     * Prepare the divs that will be used for modal with options
     */
    function prepareModal() {

        // Checks has been created
        if (document.querySelector('.pk-overlay')) {
            return;
        }

        var overlay = document.createElement('div');
        overlay.setAttribute('class', 'pk-overlay');

        var modal = document.createElement('div');
        modal.setAttribute('class', 'pk-modal');

        var mainModal = document.createElement('ul');
        mainModal.setAttribute('class', 'main');

        var head = document.createElement('div');
        head.setAttribute('class', 'head');

        var search = document.createElement('div');
        search.setAttribute('class', 'pk-search');
        var inputSearch = document.createElement('input');
        inputSearch.setAttribute('type', 'text');

        var close = document.createElement('span');
        close.setAttribute('class', 'close');
        close.innerHTML = '&times;';

        document.body.appendChild(overlay);
        document.body.appendChild(modal);
        modal.appendChild(head);
        modal.appendChild(search);
        search.appendChild(inputSearch);
        modal.appendChild(close);
        modal.appendChild(mainModal);

        // Event listener
        overlay.addEventListener('click', function (e) {
            e.preventDefault();
            e.stopPropagation();

            closeModal();
        }, false);

        close.addEventListener('click', function (e) {
            e.preventDefault();
            e.stopPropagation();

            closeModal();
        }, false);

    }

    /**
     * Resume normal classes and removes the content from within the modal
     * @param  {object DOM} overlay
     * @param  {object DOM} modal
     */
    function closeModal() {
        var overlay = document.querySelector('.pk-overlay');
        var modal = document.querySelector('.pk-modal');
        var search = modal.querySelector('.pk-search');

        overlay.setAttribute('class', 'pk-overlay');
        modal.setAttribute('class', 'pk-modal');
        search.setAttribute('class', 'pk-search');
        setTimeout(function () {
            modal.querySelector('.main').innerHTML = '';
        }, 500);
    }

    /**
     * Merges the settings passed by the user with the default settings of the package, adding their own configurations
     */
    function mergeToDefaults(config) {

        ownConfig = JSON.parse(JSON.stringify(defaults));

        for (var item in config) {
            if (config.hasOwnProperty(item)) {
                ownConfig[item] = config[item];
            }
        }

    }

    // Revealing the methods that shall be public
    return {
        to: init,
        updated: setInitialValue
    };

})();

if (typeof module !== 'undefined' && module.exports) {
    module.exports = pickout;
}